package com.luo.demo.scg.client.config;

import org.springframework.boot.web.reactive.filter.OrderedWebFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import org.springframework.web.util.pattern.PathPatternParser;
import reactor.core.publisher.Mono;

/**
 * 网关全局CORS配置<br/>
 * 注：通过spring.cloud.gateway.globalcors配置并未生效，故使用此代码配置。<br/>
 * 后续升级SCG版本可再测试下是否好用。<br/>
 * 该类仅用作临时开发，后续若使用此实现需将设置项提取成配置属性。
 *
 * @author luohq
 * @date 2022-06-10
 */
@Configuration
public class GwCorsFilter {

    @Bean
    public WebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        //允许cookies跨域
        config.setAllowCredentials(true);
        //允许向该服务器提交请求的URI，*表示全部允许，在SpringMVC中，如果设成*，会自动转成当前请求头中的Origin
        //注：setAllowCredentials为true时，allowedOrigin不能为*
        config.addAllowedOrigin("http://spa-frontend-mock-prod:8092");
        config.addAllowedOrigin("https://spa-frontend-mock-prod:8092");
        //config.addAllowedOrigin("*");
        //允许访问的头信息,*表示全部
        //config.addAllowedHeader("*");
        config.addAllowedHeader("Content-Type");
        config.addAllowedHeader("Authorization");
        config.addAllowedHeader("X-Requested-With");
        //预检请求的缓存时间（秒），即在这个时间段里，对于相同的跨域请求不会再预检了
        config.setMaxAge(86400L);
        //允许提交请求的方法类型，*表示全部允许
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");

        org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource source =
                new org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        //return new CorsWebFilter(source);

        //不使用此OrderedWebFilter，则SPA跨域访问则返回结果没有响应头Access-Control-Allow-Origin
        return new OrderedWebFilter() {
            private CorsWebFilter corsWebFilter = new CorsWebFilter(source);

            @Override
            public int getOrder() {
                return Ordered.HIGHEST_PRECEDENCE;
            }

            @Override
            public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
                return this.corsWebFilter.filter(exchange, chain);
            }
        };
    }
}

